import subprocess
from config import ADB_PATH, ADB_SERVERS
import cv2
import numpy as np
import time

from device.device_base import DeviceBase

class DeviceADB(DeviceBase):
    adb_path = ADB_PATH

    @staticmethod
    def device_list() -> list[tuple[str, str]]:
        command = f"{ADB_PATH} devices -l"
        result = subprocess.run(command, shell=True, capture_output=True)
        ans = []
        devices = result.stdout.decode("utf-8").split("\r\n")
        for device in devices:
            device_idx = device.find('device:')
            if device_idx != -1:
                ans.append((device[:device.find(' ')], device[device_idx+7:]))    
        return ans
    
    def __init__(self, device_id:str=None, sleep:float=1):
        for adb_server in ADB_SERVERS:
            command = f"{self.adb_path} connect {adb_server}"
            subprocess.run(command, shell=True)
        if device_id is None:
            devices = DeviceADB.device_list()
            if len(devices) > 0:
                device_id = devices[0][0]
        self.device_id = device_id
        self.adb_command_prefix = f"{self.adb_path} -s {self.device_id}" if self.device_id else f"{self.adb_path}"
        super().__init__()
        self.sleep = sleep
    
    def tap(self, x:int, y:int):
        command = f"{self.adb_command_prefix} shell input tap {x} {y}"
        subprocess.run(command, shell=True)
        self.record(x,y,'tap')
        time.sleep(self.sleep)

    def back(self):
        command = f"{self.adb_command_prefix} shell input keyevent 4"
        subprocess.run(command, shell=True)
        time.sleep(self.sleep)

    def long_press(self, x:int, y:int, seconds:int=1):
        command = f"{self.adb_command_prefix} shell input swipe {x} {y} {x} {y} {seconds*1000}"
        subprocess.run(command, shell=True)
        self.record(x,y,'long_press')
        time.sleep(self.sleep)
        
    def swipe_up(self, x:int=None):
        if x is None:
            x = self.screen_center[0]
        y = 0
        command = f"{self.adb_command_prefix} shell input swipe {x} {self.screen_center[1]} {x} {y} 300"
        subprocess.run(command, shell=True)
        time.sleep(self.sleep)
    
    def swipe_down(self, x:int=None):
        if x is None:
            x = self.screen_center[0]
        y = self.screen_height
        command = f"{self.adb_command_prefix} shell input swipe {x} {self.screen_center[1]} {x} {y} 300"
        subprocess.run(command, shell=True)
        time.sleep(self.sleep)
    
    def swipe_left(self, y:int=None):
        if y is None:
            y = self.screen_center[1]
        x = 0
        command = f"{self.adb_command_prefix} shell input swipe {self.screen_center[0]} {y} {x} {y} 300"
        subprocess.run(command, shell=True)
        time.sleep(self.sleep)
    
    def swipe_right(self, y:int=None):
        if y is None:
            y = self.screen_center[1]
        x = self.screen_width
        command = f"{self.adb_command_prefix} shell input swipe {self.screen_center[0]} {y} {x} {y} 300"
        subprocess.run(command, shell=True)
        time.sleep(self.sleep)

    def screenshot(self):
        command = f"{self.adb_command_prefix} exec-out screencap -p"
        result = subprocess.run(command, shell=True, capture_output=True)
        # result.stdout =  result.stdout.replace(b'\r\n', b'\n')
        img = np.frombuffer(result.stdout, dtype=np.uint8)
        img = cv2.imdecode(img, cv2.IMREAD_COLOR)
        self.screen = img